package com.yunzai.secure.config;

import com.yunzai.secure.filter.TokenFilter;
import com.yunzai.secure.handler.YunzaiLogoutSuccessHandler;
import com.yunzai.secure.point.YunzaiAuthenticationEntryPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity//(debug = true)
@EnableMethodSecurity
public class SecurityConfig {

    @Autowired
    private TokenFilter tokenFilter;

    @Autowired
    private YunzaiLogoutSuccessHandler yunzaiLogoutSuccessHandler;

    @Autowired
    private YunzaiAuthenticationEntryPoint yunzaiAuthenticationEntryPoint;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public SecurityFilterChain configure(HttpSecurity http) throws Exception {
        http.csrf(AbstractHttpConfigurer::disable)
                .formLogin(AbstractHttpConfigurer::disable)
                .sessionManagement(session -> {
                    session.disable();
                    session.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
                })
                .addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class)
                .logout(l -> {
                    l.logoutSuccessHandler(yunzaiLogoutSuccessHandler);
                })
                .exceptionHandling(a -> {
                    a.authenticationEntryPoint(yunzaiAuthenticationEntryPoint);
                })
                .authorizeHttpRequests(auth -> auth
                        // 公开访问的路径
                        .requestMatchers("/chat/ws**").permitAll()
                        .requestMatchers(HttpMethod.GET, "/code", "/logout", "/register/code/*", "/download/*", "/avatar/*").permitAll()
                        .requestMatchers(HttpMethod.POST, "/login", "/register").permitAll()
                        // 其他路径需要认证
                        .anyRequest().authenticated()
                );
        return http.build();
    }

}
